/**************************************************************************//**
 * @item     CosyOS Config
 * @file     mcucfg_80251.h
 * @brief    80251 Core Config File
 * @author   迟凯峰
 * @version  V3.3.8
 * @date     2023.09.18
 ******************************************************************************/

#ifndef __MCUCFG_80251_H
#define __MCUCFG_80251_H

/******************************************************************************
 *                             USER Definitions                               *
 ******************************************************************************/

          //*** <<< Use Configuration Wizard in Context Menu >>> ***//

///////////////////////////////////////////////////////////////////////////////
// <h> 编译器设置
// <i> 编译器设置

// <o> Code Rom Size
// <0=> Large <1=> Huge
// <i> 此项设置务必要与编译器的实际设置保持一致，否则CosyOS将无法正常运行。
#define MCUCFG_CODEROMSIZE              0

// <q> 4 Byte Interrupt Frame Size
// <i> 此项设置务必要与编译器的实际设置保持一致，否则CosyOS将无法正常运行。
#define MCUCFG_4BYTEINTFRAME            1

// </h>
///////////////////////////////////////////////////////////////////////////////
// <h> 任务栈模式
// <i> 任务栈模式分为MSP模式、MSP+PSP模式（虚拟双栈指针模式），您只能选其一。
// <i> MSP模式，与51单片机的任务栈模式相同，任务切换时是要拷贝数据的，效率低，但同时却拥有100%可靠的任务栈重分配机制，只要主栈和内存池足够大就可确保所有任务栈永不溢出。
// <i> MSP+PSP模式，任务切换效率等同于Cortex-M，但每个任务栈都是主栈，需配置足够大的edata内存。
// <i> 如果您的MCU有edata内存且足够大，可以考虑MSP+PSP模式，以提高任务切换效率。

// <e> MSP模式
// <i> 是否启用MSP模式？
#define __MCUCFG_MSPMODE                0
// <o> 最低优先级中断REGBANK
// <0=> bank0 <1=> bank1 <2=> bank2 <3=> bank3
// <i> 所有最低优先级中断的REGBANK，bank0为不使用独立的REGBANK。
#define MCUCFG_STKREGBANK               0
// </e>

// <e> MSP+PSP模式
// <i> 是否启用MSP+PSP模式（虚拟双栈指针模式）？
#define __MCUCFG_MSPPSPMODE             1

#if   __MCUCFG_MSPMODE == 1 && __MCUCFG_MSPPSPMODE == 0
#define MCUCFG_TASKSTACKMODE            __MSP__
#elif __MCUCFG_MSPMODE == 0 && __MCUCFG_MSPPSPMODE == 1
#define MCUCFG_TASKSTACKMODE            __MSP_PSP__
#elif __MCUCFG_MSPMODE == 0 && __MCUCFG_MSPPSPMODE == 0
#error 任务栈模式未定义！
#elif __MCUCFG_MSPMODE == 1 && __MCUCFG_MSPPSPMODE == 1
#error 任务栈模式重定义！
#endif

#if MCUCFG_TASKSTACKMODE == __MSP_PSP__

// <o> 任务管理器的任务栈大小
// <i> 单位为字节数
#define __STACKSIZE_TASKMGR__           128

// <o> 系统调试任务的任务栈大小
// <i> 单位为字节数
#define __STACKSIZE_DEBUGGER__          128

// <o> 系统启动任务的任务栈大小
// <i> 单位为字节数
#define __STACKSIZE_STARTER__           128

// <o> 系统空闲任务的任务栈大小
// <i> 单位为字节数
#define __STACKSIZE_SYSIDLE__           128

// <q> 任务栈监控
// <i> 是否开启任务栈监控？
// <i> 建议在调试阶段开启此项功能，正式的产品可禁用以提高性能。
#define MCUCFG_TASKSTACKMONITOR         1
#if SYSCFG_DEBUGGING == 0 && MCUCFG_TASKSTACKMONITOR == 1
#error 未启用DEBUG接口，不能开启任务栈监控！
#endif

#endif
// </e>
// </h>
///////////////////////////////////////////////////////////////////////////////
// <h> 挂起服务中断设置
// <i> 您可选择一个未使用的硬件中断，用于执行系统的挂起服务（包括中断异步服务、任务调度与切换）。
// <i> 还需在初始化钩子中配置该中断，确保它不会被硬件触发，中断优先级必须为最低级。

// <o> 中断向量号
// <i> 中断向量号
#define MCUCFG_PSVIRQ                   

// <o> 中断关闭
// <i> 此项您应在文本编辑界面中定义。
// <i> 示例：EX0 = 0
#define mPSV_Disable                    

// <o> 中断开启
// <i> 此项您应在文本编辑界面中定义。
// <i> 示例：EX0 = 1
#define mPSV_Enable                     

// <o> 中断触发
// <i> 置中断标志位
// <i> 此项您应在文本编辑界面中定义。
// <i> 示例：IE0 = 1
#define mPSV_Trigger                    

// <o> 中断清零
// <i> 清中断标志位，如果该标志位能够在中断服务程序中硬件自动清零，此项定义可以为空（不写）。
// <i> 此项您应在文本编辑界面中定义。
// <i> 示例：IE0 = 0
#define mPSV_Clear                      

// </h>
///////////////////////////////////////////////////////////////////////////////
// <o> 中断异步服务总数
// <i> 取值范围：<0~64>
// <i> 对于251单片机，您在中断中每调用一次异步服务，都要输入一个唯一的服务ID，此项用于定义您在中断中调用异步服务的总次数。
// <i> 示例：如果异步服务总数为10，那么您在中断中最多只能调用10次异步服务，服务ID为0~9。
#define MCUCFG_ISVTOTAL                 0
///////////////////////////////////////////////////////////////////////////////
// <h> 动态内存设置
// <i> CosyOS会使用下列参数自动初始化内存池。

// <o> 内存池指针
// <i> 内存池的起始内存地址
#define MCUCFG_MALLOCMEMBPTR            4096
#if !MCUCFG_MALLOCMEMBPTR
#error 非法的设置值！
#endif

// <o> 内存池大小
// <i> 内存池的大小（字节数）
#define MCUCFG_MALLOCMEMSIZE            4096
#if !MCUCFG_MALLOCMEMSIZE
#error 非法的设置值！
#endif

// </h>
///////////////////////////////////////////////////////////////////////////////

                //*** <<< end of configuration section >>> ***//

/******************************************************************************
 *                               OS Definitions                               *
 ******************************************************************************/

/* Header */
#include <string.h>
#include <intrins.h>
#include SYSCFG_STANDARDHEAD
#include "..\System\os_typedef.h"

/* Memory */
#define _SYS_MEM_     data
#define _CODE_MEM_
#define _CONST_MEM_
#define _STACK_MEM_
#define _MALLOC_MEM_
#define _XDATA_MEM_
#define _DEBUG_MEM_   xdata

/* Register */
#define _SYS_REG_

/* Typedef */
typedef bit  tBIT;
typedef u16  tSP;
typedef u16  tStackSize;
#if MCUCFG_CODEROMSIZE == 0
typedef u16  tPSP;
#else
typedef u32  tPSP;
#endif
typedef u8   tDM;
typedef u32  tPC;
typedef u32  tGRP;
typedef u32  tSysTick;
typedef u16  tFetion;

/* Extern */
extern bit vISV_FF;
extern bit vISV_F0;
extern bit vISV_F1;
extern bit vISV_F2;
extern bit vISV_F3;
extern bit vISV_F4;
extern bit vISV_F5;
extern bit vISV_F6;
extern bit vISV_F7;
extern bit vISV_F8;
extern bit vISV_F9;
extern bit vISV_F10;
extern bit vISV_F11;
extern bit vISV_F12;
extern bit vISV_F13;
extern bit vISV_F14;
extern bit vISV_F15;
extern bit vISV_F16;
extern bit vISV_F17;
extern bit vISV_F18;
extern bit vISV_F19;
extern bit vISV_F20;
extern bit vISV_F21;
extern bit vISV_F22;
extern bit vISV_F23;
extern bit vISV_F24;
extern bit vISV_F25;
extern bit vISV_F26;
extern bit vISV_F27;
extern bit vISV_F28;
extern bit vISV_F29;
extern bit vISV_F30;
extern bit vISV_F31;
extern bit vISV_F32;
extern bit vISV_F33;
extern bit vISV_F34;
extern bit vISV_F35;
extern bit vISV_F36;
extern bit vISV_F37;
extern bit vISV_F38;
extern bit vISV_F39;
extern bit vISV_F40;
extern bit vISV_F41;
extern bit vISV_F42;
extern bit vISV_F43;
extern bit vISV_F44;
extern bit vISV_F45;
extern bit vISV_F46;
extern bit vISV_F47;
extern bit vISV_F48;
extern bit vISV_F49;
extern bit vISV_F50;
extern bit vISV_F51;
extern bit vISV_F52;
extern bit vISV_F53;
extern bit vISV_F54;
extern bit vISV_F55;
extern bit vISV_F56;
extern bit vISV_F57;
extern bit vISV_F58;
extern bit vISV_F59;
extern bit vISV_F60;
extern bit vISV_F61;
extern bit vISV_F62;
extern bit vISV_F63;
extern u32 _SYS_MEM_ vPSP;
extern tSP _SYS_MEM_ vMSP;
extern tSP _SYS_MEM_ vBSP;
extern void *vISS[MCUCFG_ISVTOTAL];
extern volatile tBIT vIRQ_f;
extern volatile u8 _SYS_MEM_ vGlobalCritical;
extern void __isv_handler(void);
extern bool __enter_critical_ret(void);
extern bool __exit_critical_ret (void);
extern void __enter_critical_rec(void);
extern void __exit_critical_rec (void);
extern void __disable_irq_rec(void);
extern void __resume_irq_rec(void);
extern void __disable_irq_norec(void);
extern void __mu_task_scheduler(void);

/* * */
#pragma WARNING DISABLE = 177
#define MCUCFG_MCUARC         !__ARM__
#define MCUCFG_PCLEN          4
#define __C51USING__
#define __STK_ATTRIBUTE__     interrupt 1 __USING__
#define __PSV_ATTRIBUTE__     interrupt MCUCFG_PSVIRQ __USING__
#define __251_REENTRANT__     reentrant
#define __BSP_ALIGN__
#define MCUCFG_DIRMSGTYPE     0
#define __DM_PSP__
#define __DM_SIZE__           (&mx - &m0 - 1)
#if SYSCFG_DIRMSGMODE == __PERFORMANCE__
#define __DM_VAR__            tDM m0_
#define __DM_VAL__            1
#elif SYSCFG_DIRMSGMODE == __INTELLIGENT__
#define __DM_VAR__            u32 DR0_, u32 DR4_, tDM R11_, tDM m0_
#define __DM_VAL__            0, 0, 0, 1
#endif

/* API */
#define mSysTick_CLKMOD       (SYSCFG_SYSCLK / (1000000UL / SYSCFG_STKCYCLE) <= 65536 ? 1 : 12)
#define mSysTick_Cycle        (SYSCFG_SYSCLK / (1000000UL / SYSCFG_STKCYCLE) / mSysTick_CLKMOD)
#if mSysTick_Cycle > 65536
#error 系统滴答定时器溢出，必须减小系统时钟或系统滴答周期。
#elif 1000000UL % SYSCFG_STKCYCLE
#warning 每秒钟的系统滴答周期数不为整数，建议重新调整系统滴答周期。
#elif SYSCFG_SYSCLK % (1000000UL / SYSCFG_STKCYCLE)
#warning 每秒钟的系统滴答周期数不为整数，建议重新调整系统时钟或系统滴答周期。
#elif SYSCFG_SYSCLK / (1000000UL / SYSCFG_STKCYCLE) % mSysTick_CLKMOD
#warning 每秒钟的系统滴答周期数不为整数，建议重新调整系统时钟或系统滴答周期。
#endif
#define mSysTick_InitValue    (65536 - mSysTick_Cycle)
#define mSysTick_Counter      ((TH0 << 8) | TL0)
#define mSTK_Disable          ET0 = 0
#define mSTK_Enable           ET0 = 1

#define mEnterCritical	\
do{	\
	mPSV_Disable;	\
	mSTK_Disable;	\
}while(false)

#define mExitCritical	\
do{	\
	mSTK_Enable;	\
	mPSV_Enable;	\
}while(false)

#define mEnterCritical_rec __enter_critical_rec()
#define mExitCritical_rec  __exit_critical_rec()

#if SYSCFG_GLOBALCRITICAL == __ENABLED__
#define mDisableIRQ	__disable_irq_rec()
#define mResumeIRQ	__resume_irq_rec()
#else
#define mDisableIRQ	__disable_irq_norec()
#define mResumeIRQ  EA = vIRQ_f
#endif

#define muTaskScheduler __mu_task_scheduler()
#define miTaskScheduler	\
do{	\
	vScheduling_f = true;	\
	mPSV_Trigger;	\
}while(false)

#define mSys_Idle	\
do{	\
	PCON |= 0x01;	\
	OS_NOPx4;	\
}while(false)

#define mSys_init	\
do{	\
	__init_mempool((void _MALLOC_MEM_ *)MCUCFG_MALLOCMEMBPTR, MCUCFG_MALLOCMEMSIZE);	\
	OS_NOPx1;	\
	AUXR = mSysTick_CLKMOD == 1 ? AUXR | 0x80 : AUXR &~0x80;	\
	TMOD &= 0xF0;	\
	TL0 = (u8)(mSysTick_InitValue);	\
	TH0 = (u8)(mSysTick_InitValue >> 8);	\
	TR0 = 1;	\
	mSTK_Enable;	\
	mPSV_Enable;	\
	EA = 1;	\
}while(false)

#define mTaskmgr_Counting	\
	counter2 = (counter1 * 100 * mSysTick_CLKMOD) / (SYSCFG_SYSCLK / 1000000UL) / counter2

#define mSTK_Counting	\
do{	\
	if(mSysTick_Counter <= tick_temp) break;	\
	vSTK_Counter1 += mSysTick_Counter - tick_temp;	\
	vSTK_Counter2++;	\
}while(false)

#if SYSCFG_SAFERUNTIME == __ENABLED__
#define mSRT_Monitor    \
if(vTASKING->TPL > node_news->TPL)	\
{	\
	vTASKING->counter = 0;	\
}
#else
#define mSRT_Monitor
#endif

#if SYSCFG_TASKPCMONITOR == __ENABLED__
#define mTaskPC_Monitor	\
do{	\
	if(!vTaskmgrBinary) break;	\
	vPSP -= (__BASICSTACKSIZE__ - 1);	\
	vPC = *(tPC *)vPSP;	\
	vPC = ((u16)vPC << 8) | ((u16)vPC >> 8) | (vPC & 0xFFFF0000);	\
}while(false)
#else
#define mTaskPC_Monitor do{}while(false)
#endif

#define mUsedTime_END	\
do{	\
	if(usedtime[0])	\
	{	\
		usedtime[0]--;	\
		usedtime[1] = 65536 - usedtime[1] + counter - mSysTick_InitValue;	\
	}	\
	else	\
	{	\
		if(counter >= usedtime[1])	\
		{	\
			usedtime[1] = counter - usedtime[1];	\
		}	\
		else	\
		{	\
			usedtime[1] = 65536 - usedtime[1] + counter - mSysTick_InitValue;	\
		}	\
	}	\
	vTASKING->usedtime[0] += usedtime[0];	\
	vTASKING->usedtime[0] += (vTASKING->usedtime[1] + usedtime[1]) / mSysTick_Cycle;	\
	vTASKING->usedtime[1]  = (vTASKING->usedtime[1] + usedtime[1]) % mSysTick_Cycle;	\
}while(false)

#define mUsedTime_INIT	\
do{	\
	usedtime[0] = 0;	\
	usedtime[1] = counter;	\
}while(false)

#define mISV_Do(svid)	\
do{	\
	vISS[svid] = &isv_;	\
	vISV_F##svid = true;	\
	vISV_FF = true;	\
	mPSV_Trigger;	\
}while(false)

#define mISV	\
	mPSV_Clear;	\
	if(vISV_FF) __isv_handler()

#define miWriteFlagBits	\
	if(!isv_.value)	\
	{	\
		do{}while(false)



/*
 * MSP模式
 */

#if MCUCFG_TASKSTACKMODE == __MSP__

/* * */
#define MCUCFG_TASKSTACKMONITOR __DISABLED__
#if MCUCFG_STKREGBANK
#define __USING__               using MCUCFG_STKREGBANK
#define __REGSIZE__             8
#define __BASICSTACKSIZE__      (32 - MCUCFG_4BYTEINTFRAME)
#else
#define __USING__
#define __REGSIZE__             0
#define __BASICSTACKSIZE__      (40 - MCUCFG_4BYTEINTFRAME)
#endif
#define __STACKSIZE_TASKMGR__   (SYSCFG_TASKCREATEMODE ? __BASICSTACKSIZE__ : __BASICSTACKSIZE__ + 16)
#define __STACKSIZE_DEBUGGER__  (SYSCFG_TASKCREATEMODE ? __BASICSTACKSIZE__ : __BASICSTACKSIZE__ + 16)
#define __STACKSIZE_STARTER__   (SYSCFG_TASKCREATEMODE ? __BASICSTACKSIZE__ : __BASICSTACKSIZE__ + 16)
#define __STACKSIZE_SYSIDLE__   (SYSCFG_TASKCREATEMODE ? __BASICSTACKSIZE__ : __BASICSTACKSIZE__ + 16)

/* API */
#define mTaskNode_Head_       tStackSize stacklen;
#if __REGSIZE__
#define mTaskNode_Tail_       u8 reg[__REGSIZE__];
#define mReg_PUSH	\
	*(u32 *)(vTASKING->reg + 0) = *(u32 _SYS_MEM_ *)0;	\
	*(u32 *)(vTASKING->reg + 4) = *(u32 _SYS_MEM_ *)4
#define mReg_POP	\
	*(u32 _SYS_MEM_ *)0 = *(u32 *)(vTASKING->reg + 0);	\
	*(u32 _SYS_MEM_ *)4 = *(u32 *)(vTASKING->reg + 4)
#else
#define mTaskNode_Tail_
#define mReg_PUSH do{}while(false)
#define mReg_POP  do{}while(false)
#endif

#define mSys_INIT	\
do{	\
	vMSP = (SPH << 8) | SP;	\
	vBSP = vMSP + 1;	\
	mSys_init;	\
}while(false)

#define mScheduler_INIT	\
	u8  i;	\
	tStackSize stacklen;	\
	u8  _STACK_MEM_  *msp8;	\
	u8  _MALLOC_MEM_ *psp8;	\
	u32 _STACK_MEM_  *msp32;	\
	u32 _MALLOC_MEM_ *psp32;	\
	vScheduling_f = false;	\
	__asm{MOV vPSP, DR60}

#define mTaskStack_INIT	\
do{	\
	*(u32 *)node_news->BSP = ((u16)vACTBUF->entry << 8) | ((u16)vACTBUF->entry >> 8) | ((u32)vACTBUF->entry & 0xFFFF0000);	\
	*(u8 *)(node_news->BSP + __BASICSTACKSIZE__ - 3) = 0;	\
	node_news->stacklen = __BASICSTACKSIZE__;	\
}while(false)

#define mTaskStack_LEN	\
	stacklen = (tSP)vPSP - vMSP

#define mEvery_Monitor do{}while(false)

#if SYSCFG_DEBUGGING == __ENABLED__
#if SYSCFG_TASKCREATEMODE == __STATIC__
#define mPUSH_Monitor	\
do{	\
	if(vTASKING->stacksize < stacklen)	\
	{	\
		vTASKING->state = __STOPPED_TSOF__;	\
		vFault.overflow_taskstack = true;	\
	}	\
	else	\
	{	\
		push_f = true;	\
		mSRT_Monitor    \
	}	\
}while(false)
#else
#define mPUSH_Monitor	\
do{	\
	if(vTASKING->stacksize < stacklen)	\
	{	\
		vTASKING->stacksize = stacklen;	\
		__free(vTASKING->BSP);	\
		vTASKING->BSP = NULL;	\
		vTASKING->BSP = (u8 *)__malloc(vTASKING->stacksize);	\
		if(vTASKING->BSP != NULL)	\
		{	\
			vTASKING->realloc = true;	\
			push_f = true;	\
		}	\
		else	\
		{	\
			vTASKING->state = __STOPPED_TSRF__;	\
			vFault.reallocfail_taskstack = true;	\
		}	\
	}	\
	else	\
	{	\
		push_f = true;	\
	}	\
	if(push_f)	\
	{	\
		mSRT_Monitor    \
	}	\
}while(false)
#endif
#else
#if SYSCFG_TASKCREATEMODE == __STATIC__
#define mPUSH_Monitor	\
do{	\
	if(vTASKING->stacksize < stacklen)	\
	{	\
		vTASKING->state = __STOPPED_TSOF__;	\
	}	\
	else	\
	{	\
		push_f = true;	\
		mSRT_Monitor    \
	}	\
}while(false)
#else
#define mPUSH_Monitor	\
do{	\
	if(vTASKING->stacksize < stacklen)	\
	{	\
		vTASKING->stacksize = stacklen;	\
		__free(vTASKING->BSP);	\
		vTASKING->BSP = NULL;	\
		vTASKING->BSP = (u8 *)__malloc(vTASKING->stacksize);	\
		if(vTASKING->BSP != NULL)	\
		{	\
			push_f = true;	\
		}	\
		else	\
		{	\
			vTASKING->state = __STOPPED_TSRF__;	\
		}	\
	}	\
	else	\
	{	\
		push_f = true;	\
	}	\
	if(push_f)	\
	{	\
		mSRT_Monitor    \
	}	\
}while(false)
#endif
#endif

#define mTaskStack_PUSH	\
do{	\
	msp32 = (u32 _STACK_MEM_  *)vBSP;	\
	psp32 = (u32 _MALLOC_MEM_ *)vTASKING->BSP;	\
	vTASKING->stacklen = stacklen;	\
	i = stacklen >> 2;	\
	do{	\
		*psp32++ = *msp32++;	\
	}while(--i);	\
	i = stacklen & 3;	\
	if(i)	\
	{	\
		msp8 = (u8 _STACK_MEM_  *)msp32;	\
		psp8 = (u8 _MALLOC_MEM_ *)psp32;	\
		do{	\
			*psp8++ = *msp8++;	\
		}while(--i);	\
	}	\
	mReg_PUSH;	\
	mTaskPC_Monitor;	\
}while(false)

#define mTaskStack_POP	\
do{	\
	vTASKING = node_news;	\
	msp32 = (u32 _STACK_MEM_  *)vBSP;	\
	psp32 = (u32 _MALLOC_MEM_ *)vTASKING->BSP;	\
	stacklen = vTASKING->stacklen;	\
	i = stacklen >> 2;	\
	do{	\
		*msp32++ = *psp32++;	\
	}while(--i);	\
	i = stacklen & 3;	\
	if(i)	\
	{	\
		msp8 = (u8 _STACK_MEM_  *)msp32;	\
		psp8 = (u8 _MALLOC_MEM_ *)psp32;	\
		do{	\
			*msp8++ = *psp8++;	\
		}while(--i);	\
	}	\
	mReg_POP;	\
	vPSP = vMSP + stacklen;	\
	__asm{MOV DR60, vPSP};	\
}while(false)



/*
 * MSP+PSP模式
 */

#elif MCUCFG_TASKSTACKMODE == __MSP_PSP__

/* * */
#define __USING__
#define __BASICSTACKSIZE__    (40 - MCUCFG_4BYTEINTFRAME)

/* API */
#define mTaskNode_Head_       tPSP PSP;
#define mTaskNode_Tail_

#define mSys_INIT	\
do{	\
	vMSP = (SPH << 8) | SP;	\
	mSys_init;	\
}while(false)

#define mScheduler_INIT	\
	tStackSize stacklen;	\
	vScheduling_f = false;	\
	__asm{MOV vPSP, DR60}

#define mTaskStack_INIT	\
do{	\
	*(u32 *)node_news->BSP = ((u16)vACTBUF->entry << 8) | ((u16)vACTBUF->entry >> 8) | ((u32)vACTBUF->entry & 0xFFFF0000);	\
	*(u8 *)(node_news->BSP + __BASICSTACKSIZE__ - 3) = 0;	\
	node_news->PSP = (tSP)node_news->BSP + __BASICSTACKSIZE__ - 1;	\
}while(false)

#define mTaskStack_LEN	\
	stacklen = (tSP)vPSP + 1 - (tSP)vTASKING->BSP

#if MCUCFG_TASKSTACKMONITOR == __ENABLED__
#define mEvery_Monitor	\
do{	\
	if(vTASKING->stacksize < stacklen)	\
	{	\
		vTASKING->state = __STOPPED_TSOF__;	\
		vFault.overflow_taskstack = true;	\
	}	\
}while(false)
#else
#define mEvery_Monitor do{}while(false)
#endif

#define mPUSH_Monitor	\
do{	\
	push_f = true;	\
	mSRT_Monitor    \
}while(false)

#define mTaskStack_PUSH	\
do{	\
	vTASKING->PSP = vPSP;	\
	mTaskPC_Monitor;	\
}while(false)

#define mTaskStack_POP	\
do{	\
	vTASKING = node_news;	\
	vPSP = vTASKING->PSP;	\
	__asm{MOV DR60, vPSP};	\
}while(false)

#endif

#endif
